package com.db.utils;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class DateUtil {

/*    private static final SimpleDateFormat DATEFORMAT = new SimpleDateFormat("yyyy/MM/dd");
    private static final SimpleDateFormat MONTHFORMAT = new SimpleDateFormat("yyyy/MM");
    private static final SimpleDateFormat TIMEFORMAT = new SimpleDateFormat("yyyyMMddHHmmssSSS");
    private static final SimpleDateFormat DATETOSTRING = new SimpleDateFormat("yyyy-MM-dd");
    private static final SimpleDateFormat YearMonthDate = new SimpleDateFormat("yyyy年MM月dd日");
    private static final SimpleDateFormat MMDDHHMM = new SimpleDateFormat("MM月dd日 HH:mm");
    private static final SimpleDateFormat YYYYMMDD = new SimpleDateFormat("yyyyMMdd");
    private static final SimpleDateFormat YYMMDDHHMMS = new SimpleDateFormat("yyMMddHHmms");
    private static final SimpleDateFormat YYMMDDHHMMSS = new SimpleDateFormat("yyMMddHHmmss");
    private static final SimpleDateFormat HH = new SimpleDateFormat("HH");
    private static final SimpleDateFormat HHmm = new SimpleDateFormat("HH:mm");
    private static final SimpleDateFormat HH_MM_SS = new SimpleDateFormat("HH:mm:ss");
    private static final SimpleDateFormat HHMMSS = new SimpleDateFormat("HHmmss");
    private static final SimpleDateFormat YYYYMMDDHHMMSSS = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    private final static String DATE_FORMAT_DATE = "yyyy-MM-dd";
    private static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'Z";
    private static final SimpleDateFormat GELINFormatter = new SimpleDateFormat(DATE_FORMAT, Locale.US);
*/

    /** 锁对象 */
    private static final Object lockObj = new Object();

    /** 存放不同的日期模板格式的sdf的Map */
    private static Map<String, ThreadLocal<SimpleDateFormat>> sdfMap = new HashMap<String, ThreadLocal<SimpleDateFormat>>();

    /**
     * 返回一个ThreadLocal的sdf,每个线程只会new一次sdf
     *
     * @param pattern
     * @return
     */
    private static SimpleDateFormat getSdf(final String pattern) {
        ThreadLocal<SimpleDateFormat> tl = sdfMap.get(pattern);

        // 此处的双重判断和同步是为了防止sdfMap这个单例被多次put重复的sdf
        if (tl == null) {
            synchronized (lockObj) {
                tl = sdfMap.get(pattern);
                if (tl == null) {
                    // 只有Map中还没有这个pattern的sdf才会生成新的sdf并放入map
                    //System.out.println("put new sdf of pattern " + pattern + " to map");
                    // 这里是关键,使用ThreadLocal<SimpleDateFormat>替代原来直接new SimpleDateFormat
                    tl = new ThreadLocal<SimpleDateFormat>() {
                        @Override
                        protected SimpleDateFormat initialValue() {
                            //System.out.println("thread: " + Thread.currentThread() + " init pattern: " + pattern);
                            return new SimpleDateFormat(pattern);
                        }
                    };
                    sdfMap.put(pattern, tl);
                }
            }
        }
        return tl.get();
    }


    //以日期格式返回日期字符串用作文件夹名
    public static String getDateFileFolder() {
        //return DATEFORMAT.format(new Date());
        return getSdf("yyyy/MM/dd").format(new Date());
    }

    public static String getTodayFolder() {
        return getSdf("yyyy-MM-dd").format(new Date());
    }

    public static String getMMDDHHMM(long time) {
        //return MMDDHHMM.format(time);
        return getSdf("MM月dd日 HH:mm").format(time);
    }

    public static String getYYYYMMDDHHMMSSS(long time) {
        //return YYYYMMDDHHMMSSS.format(time);
        return getSdf("yyyy-MM-dd HH:mm:ss").format(time);
    }

    //以月份格式返回月份字符串用作文件夹名
    public static String getMonthFileFolder() {
        //return MONTHFORMAT.format(new Date());
        return getSdf("yyyy/MM").format(new Date());
    }

    public static String getTimeFileName() {
        //return TIMEFORMAT.format(new Date());
        return getSdf("yyyyMMddHHmmssSSS").format(new Date());
    }

    public static String getSystemTimeFileName() {
        return String.valueOf(System.nanoTime());
    }

    public static String getDate() {
        //return YYYYMMDDHHMMSSS.format(new Date());
        return getSdf("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public static String getDateYYMMddHHmms() {
        //return YYMMDDHHMMS.format(new Date());
        return getSdf("yyMMddHHmms").format(new Date());
    }

    public static Date getDate(String date) {
        try {
            //return DATETOSTRING.parse(date);
            return getSdf("yyyy-MM-dd").parse(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static Date getDate2(String date) {
        try {
            //return YYYYMMDDHHMMSSS.parse(date);
            return getSdf("yyyy-MM-dd HH:mm:ss").parse(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static Date getDate3(String date) {
        try {
            //return GELINFormatter.parse(date);
            return getSdf("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'Z").parse(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getDate(Date date) {
        try {
            ///return DATETOSTRING.format(date);
            return getSdf("yyyy-MM-dd").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getYmd(Date date) {
        try {
            //return YearMonthDate.format(date);
            return getSdf("yyyy年MM月dd日").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getYyyymmdd(Date date) {
        try {
            //return YYYYMMDD.format(date);
            return getSdf("yyyyMMdd").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getYYMMDDHHMMSS() {
        try {
            //return YYMMDDHHMMSS.format(new Date());
            return getSdf("yyMMddHHmmss").format(new Date());
        } catch (Exception e) {
            return "120608101010";
        }
    }

    public static int getHH() {
    	int flag = 0;
        try {
        	//String str = HH.format(new Date());
            String str = getSdf("HH").format(new Date());
        	if (str != null) {
        		flag = Integer.valueOf(str);
			}
        } catch (Exception e) {
        }

        return flag;
    }

    public static String getHH(Date date) {
        try {
            //return HH.format(date);
            return getSdf("HH").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getHHmm(Date date) {
        try {
            //return HHmm.format(date);
            return getSdf("HH:mm").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getYYYYMMDDHHMMSSS(Date date) {
        try {
            //return YYYYMMDDHHMMSSS.format(date);
            return getSdf("yyyy-MM-dd HH:mm:ss").format(date);
        } catch (Exception e) {
            return "";
        }
    }

    public static String getHHmmss(Date date) {
        try {
            //return HH_MM_SS.format(date);
            return getSdf("HH:mm:ss").format(date);
        } catch (Exception e) {
            return null;
        }
    }

    public static String getHHmmss() {
        try {
            //return HHMMSS.format(new Date());
            return getSdf("HHmmss").format(new Date());
        } catch (Exception e) {
            return null;
        }
    }


    /**
     * 取得指定天数后的日期
     */
    public static String nextDate(int day) {
        Calendar cal = Calendar.getInstance();
        Date date = new Date();
        try {
            cal.setTime(date);
            cal.add(Calendar.DATE, day);
            return getDate(cal.getTime());
        } catch (Exception e) {
            return getDate(date);
        }
    }

    /**
     * 取得指定天数后的日期
     */
    public static String nextDate(Date date, int day) {
        Calendar cal = Calendar.getInstance();
        //Date date = new Date();
        try {
            cal.setTime(date);
            cal.add(Calendar.DATE, day);
            return getDate(cal.getTime());
        } catch (Exception e) {
            return getDate(date);
        }
    }

    /**
     *
     * 把毫秒转化成日期
     *
     * dateFormat(日期格式，例如：yyyy/MM/dd/yyyy HH:mm:ss)
     *
     * @param millSec(毫秒数)
     *
     * @return
     *
     */
    public static String longToDate(Long millSec) {
        try {
            Date date = new Date(millSec);
            //return YYYYMMDDHHMMSSS.format(date);
            return getSdf("yyyy-MM-dd HH:mm:ss").format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    /**
     *
     * 把毫秒转化成日期
     *
     * @param dateFormat(日期格式，例如：yyyy/MM/dd/yyyy HH:mm:ss)
     *
     * @param millSec(毫秒数)
     *
     * @return
     *
     */
    public static String longToDate(String dateFormat, Long millSec) {
        try {
            //SimpleDateFormat sdf = new SimpleDateFormat(dateFormat);
            SimpleDateFormat sdf = getSdf(dateFormat);
            Date date = new Date(millSec);
            return sdf.format(date);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
    }

    public static long dateToLong(String dateStr) {
        long res = System.currentTimeMillis();
        try {
            res = getDate(dateStr).getTime();
        } catch (Exception e) {
            System.out.println("时间转换异常了dateStr： "+dateStr + e.getMessage());
        }
        return res;
    }

    public static long dateToLong2(String dateStr) {
        long res = 0l;
        try {
            res = getDate2(dateStr).getTime();
        } catch (Exception e) {
            System.out.println("时间转换异常了dateStr： "+dateStr + e.getMessage());
        }
        return res;
    }

    public static long dateToLong3(String dateStr) {
        long res = 0l;
        try {
            res = getDate3(dateStr).getTime();
        } catch (Exception e) {
            System.out.println("时间转换异常了dateStr： "+dateStr + e.getMessage());
        }
        return res;
    }

    /**
     * 获取时间的当天最小值，并返回格式化后的字符串
     *
     * @param date
     * @return
     */
    public static String getMinTimeStr(Date date)
    {
        String dateStr = convertDate2Str(date, "yyyy-MM-dd");
        return dateStr + " 00:00:00";
    }

    public static String convertDate2Str(Date date, String format)
    {
        //return new SimpleDateFormat(format).format(date);
        return getSdf(format).format(date);
    }

    /**
     * 距离现在的天数
     * @param date
     * @return
     */
    public static int toNowsDays(String date) {
        return (int) ((System.currentTimeMillis()-DateUtil.dateToLong(date))/(24*60*60*1000));
    }

    /**
     * 距离现在的秒数
     * @param date
     * @return
     */
    public static int toNowsSeconds(String date) {
        return (int) ((System.currentTimeMillis()-DateUtil.dateToLong2(date))/(1*1000));
    }

    public static void main(String[] args){
        Date d1 = new Date();
        String dateStr = "2023-11-14 00:04:34";
        long ll = dateToLong2(dateStr);
        System.out.println(longToDate(ll));
        System.out.println(d1.getTime() +" "+ dateToLong2(dateStr));
        //System.out.println(getTimeStamp("yyyyMMddHHmmssSSS"));
        System.out.println(nextDate(-21));

        System.out.println("当前小时：" + getHH());

    }

}
